#include "mainwindow.h"
#include "ui_mainwindow.h"

#define BAUDRATE B115200

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

bool MainWindow::on_openButton_clicked() //bool MainWindow::openSerial()
{
    struct termios setting;
    //fd = open(qPrintable("/dev/" + setData.devName), O_RDWR);
    fd=open("/dev/ttyUSB0",O_RDWR|O_NOCTTY);//以读写方式打开串口，不控制TTY
    if(fd==-1)
    {
        QMessageBox::warning(this, "open error", strerror(errno));
        goto openerr;
    }
    tcgetattr(fd, &setting);
    cfsetispeed(&setting, BAUDRATE);//115200
    cfsetospeed(&setting, BAUDRATE);
    cfmakeraw(&setting);
    setting.c_cflag|=CS8;       //8位
    setting.c_cflag|=CLOCAL;    //忽略DCD信号
    setting.c_cflag|=CREAD;     //启动接收装置
    setting.c_iflag|=IGNPAR;    //忽略奇偶

    //setting.c_cflag&=~PARENB;   //none
    //setting.c_iflag&=~INPCK;    //none
    //setting.c_cflag &=~CSTOPB;  //1停止位

    setting.c_oflag=0;
    setting.c_lflag=0;

    setting.c_cc[VMIN]=0;
    setting.c_cc[VTIME]=100;//在规定时间（VTIME)内读取(VMIN)个字符
    tcflush(fd,TCIFLUSH);//清除所有队列在串口的输入与输出;
    tcsetattr(fd,TCSANOW,&setting);//把我们的设置写入termios

    monitor=new QSocketNotifier(fd,QSocketNotifier::Read,NULL);
    autoTimer=new QTimer;
    timer1=new QTimer;

    connect(monitor,SIGNAL(activated(int)),this,SLOT(readData()));
    connect(autoTimer,SIGNAL(timeout()),this,SLOT(on_sendButon_clicked()));
    connect(this,SIGNAL(finished()),this,SLOT(updateData()));
    connect(timer1,SIGNAL(timeout()),this,SLOT(monitorSetEndable()));

    monitor->setEnabled(true);
    ui->hexBox->setCheckState(Qt::Checked);
    ui->autoSend->setCheckState(Qt::Unchecked);
    ui->sendSpin->setValue(100);
    ui->sendInfo->clear();
    on_clearButton_clicked();

    return true;
seterr:
    ::close(fd);
openerr:
    return false;
}

void MainWindow::on_autoSend_clicked() //SerialTrans::startAutoSend()自动发送
{
    if(ui->autoSend->isChecked())
    {
        ui->sendSpin->setDisabled(true);
        autoTimer->start(ui->sendSpin->value());
    }
    else
    {
        autoTimer->stop();
        ui->sendSpin->setDisabled(false);
    }
}

void MainWindow::on_sendButon_clicked() //SerialTrans::sendData()数据发送
{
    int ret;
    //ret=write(fd,ui->sendInfo->text().toLatin1(),ui->sendInfo->text().size());
/********************************************************************************
 * 发送数据处理  2017-7-22 v1.0
 * 作者：mario
 * ******************************************************************************/
    QByteArray sendbuf;
    QString str;
    bool ok;
    char data;
    QStringList list;
    str =ui->sendInfo->text();
    list=str.split(" ");
    for(int i=0;i<list.count();i++)
    {
        if(list.at(i)==" ")
            continue;
        if(list.at(i).isEmpty())
            continue;
        data=(char)list.at(i).toInt(&ok,16);
        sendbuf.append(data);
    }
    ret=write(fd,sendbuf,sendbuf.size());
/********************************************************************************/
    ui->sendNum->display(ui->sendNum->intValue()+ret);
}

void MainWindow::on_clearButton_clicked() //SerialTrans::clearData()清除数据
{
    revData.clear();
    ui->recNum->display(0);
    ui->sendNum->display(0);
    updateData();
}

void MainWindow::updateData() //数据更新
{
    timer1->start(100);//100ms
    char *m_pData;
    int top=0;
    for(int i=0;i<66;i++)
    {
        if(0x55==buf[i])
        {
            top=i;
            break;
        }
    }
    for(int i=0;i<66;i++)
    {
        if(i+top<66)
            revbuf[i]=buf[i+top];
        else
            revbuf[i]=buf[i+top-66];
    }
    m_pData=revbuf;
    for(int i=0;i<66;i++)
    {
        QString s;
        s.sprintf("0x%02x, ",(unsigned char)*m_pData);
        revData+=s;
        m_pData=m_pData+1;
        s.clear();
    }
    ui->revInfo->setText(revData);
    revData.clear();
}

void MainWindow::readData() //读出数据
{
    int ret;
    monitor->setEnabled(false);
    //ret=read(fd,buf,sizeof(buf));
    ret=read(fd,buf,66);
    buf[ret]=0;
    emit finished();
}

void MainWindow::on_closeButton_clicked() //SerialTrans::closeSerial()
{
    ::close(fd);
    autoTimer->stop();
    timer1->stop();
    monitor->setEnabled(false);
//    delete monitor;
//    delete autoTimer;
//    delete timer1;
//    emit serialClosed();
}

void MainWindow::monitorSetEndable()
{
    timer1->stop();
    monitor->setEnabled(true);
}
